home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32_DEBUG.C < prev    next >
C/C++ Source or Header  |  1991-09-11  |  19KB  |  728 lines

  1. /* This is file DEBUG.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* History:175,26 */
  16. #include <stdio.h>
  17. #include <setjmp.h>
  18. #include <math.h>
  19. #include <dos.h>
  20.  
  21. #include "build.h"
  22. #include "types.h"
  23. #include "gdt.h"
  24. #include "tss.h"
  25. #include "utils.h"
  26. #include "unassmbl.h"
  27. #include "syms.h"
  28. #include "paging.h"
  29. #include "npx.h"
  30. #include "mono.h"
  31.  
  32. extern int was_exception, have_80387;
  33. jmp_buf back_to_debugger;
  34. int can_longjmp=0;
  35.  
  36. #if DEBUGGER
  37.  
  38. extern word32 dr[8];
  39. extern word32 dr0, dr1, dr2, dr3, dr6, dr7;
  40.  
  41. typedef struct {
  42.     char *cp;
  43.     int t;
  44.     } item;
  45.  
  46. my_getline(char *buf, char *lasttoken)
  47. {
  48.   int idx, i, ch;
  49.   if (use_ansi)
  50.     printf("\033[0;32m");
  51.   mono_attr = MONO_NORMAL;
  52.   printf(">> %s", lasttoken);
  53.   for (i=0; lasttoken[i]; i++)
  54.     mputchar(8);
  55.   while (!bioskey(1));
  56.   for (i=0; lasttoken[i]; i++)
  57.     mputchar(' ');
  58.   for (i=0; lasttoken[i]; i++)
  59.     mputchar(8);
  60.   idx = 0;
  61.   if (use_ansi)
  62.     printf("\033[1;33m");
  63.   mono_attr = MONO_BOLD;
  64.   while (1)
  65.   {
  66.     ch = bioskey(0) & 0xff;
  67.     switch (ch)
  68.     {
  69.       case 10:
  70.       case 13:
  71.         buf[idx] = 0;
  72.         if (!idx && lasttoken[0])
  73.           printf("\r  \r");
  74.         else
  75.           mputchar('\n');
  76.         if (use_ansi)
  77.           printf("\033[0m");
  78.         mono_attr = MONO_NORMAL;
  79.         return;
  80.       case 27:
  81.         while (idx)
  82.         {
  83.           printf("\b \b");
  84.           idx--;
  85.         }
  86.         break;
  87.       case 8:
  88.         if (idx)
  89.         {
  90.           printf("\b \b");
  91.           idx--;
  92.         }
  93.         break;
  94.       default:
  95.         mputchar(ch);
  96.         buf[idx++] = ch;
  97.         break;
  98.     }
  99.   }
  100. }
  101.  
  102. typedef enum { Zero, Unknown, CONT, STEP, NEXT, REGS, SET, HELP, LIST,
  103. DUMP, QUIT, BREAK, STATUS, WHERE, DUMP_A, DUMP_B, DUMP_W, WHEREIS, XNPX,
  104. CLS };
  105.  
  106. extern struct {
  107.   char *name;
  108.   int size;
  109.   int ofs;
  110.   } regs[];
  111.  
  112. item cmds[] = {
  113.     "g", CONT,
  114.     "go", CONT,
  115.     "cont", CONT,
  116.     "c", CONT,
  117.     "step", STEP,
  118.     "s", STEP,
  119.     "next", NEXT,
  120.     "n", NEXT,
  121.     "regs", REGS,
  122.     "r", REGS,
  123.     "set", SET,
  124.     "help", HELP,
  125.     "h", HELP,
  126.     "?", HELP,
  127.     "list", LIST,
  128.     "l", LIST,
  129.     "u", LIST,
  130.     "dump", DUMP,
  131.     "d", DUMP,
  132.     "da", DUMP_A,
  133.     "db", DUMP_B,
  134.     "dw", DUMP_W,
  135.     "dd", DUMP,
  136.     "quit", QUIT,
  137.     "q", QUIT,
  138.     "break", BREAK,
  139.     "b", BREAK,
  140.     "status", STATUS,
  141.     "where", WHERE,
  142.     "whereis", WHEREIS,
  143.     "npx", XNPX,
  144.     "cls", CLS,
  145.     0, 0
  146.     };
  147.  
  148. extern int debug_mode;
  149.  
  150. debugger()
  151. {
  152.   char buf[140], token[10];
  153.   char buf2[140], *name, lasttoken[140];
  154.   int i, n, s, len, rem_cmd, cmd, vstep, found;
  155.   word32 vaddr, v, rem_v, olddr7;
  156.   int32 delta;
  157.  
  158.   dr0 = dr1 = dr2 = ARENA;
  159.   dr3 = syms_name2val("_main") + ARENA;
  160.   if (undefined_symbol)
  161.     dr3 = tss_ptr->tss_eip + ARENA;
  162.   rem_cmd = Zero;
  163.   lasttoken[0] = 0;
  164.   setjmp(back_to_debugger);
  165.   can_longjmp = 1;
  166.   while (1)
  167.   {
  168.     if (debug_mode)
  169.     {
  170.       int found;
  171.       my_getline(buf, lasttoken);
  172.       token[0] = 0;
  173.       if (sscanf(buf, "%s %[^\n]", token, buf) < 2)
  174.         buf[0] = 0;
  175.       if (token[0])
  176.         strcpy(lasttoken, token);
  177.       cmd = rem_cmd;
  178.       found = 0;
  179.       for (i=0; cmds[i].cp; i++)
  180.         if (strcmp(cmds[i].cp, token) == 0)
  181.         {
  182.           cmd = cmds[i].t;
  183.           found = 1;
  184.         }
  185.       if (!found && token[0])
  186.         cmd = Unknown;
  187.       if (rem_cmd != cmd)
  188.         vaddr = tss_ptr->tss_eip;
  189.     }
  190.     else
  191.     {
  192.       cmd = CONT;
  193.       debug_mode = 1;
  194.     }
  195.     switch (cmd)
  196.     {
  197.       case HELP:
  198.         printf("Commands:\n");
  199.         printf("go <v>\tg\tgo, stop at <v>\n");
  200.         printf("cont\tc\tcontinue execution\n");
  201.         printf("step\ts\tstep through current instruction\n");
  202.         printf("next\tn\tstep to next instruction\n");
  203.         printf("list\tl u\tlist instructions (takes addr, count)\n");
  204.         printf("dump\td\tdump memory (takes addr, count)\n");
  205.         printf("break\tb\tset breakpoint (takes which, addr)\n");
  206.         printf("status\t\tbreakpoint status\n");
  207.         printf("regs\tr\tprint registers\n");
  208.         printf("set\t\tset register/memory\n");
  209.         printf("npx\t\tdisplay 80387 contents\n");
  210.         printf("where\t\tdisplay list of active functions\n");
  211.         printf("whereis\t\tfind a symbol/location (takes wildcard or value)\n");
  212.         printf("cls\t\tclear screen\n");
  213.         printf("help\th,?\tprint help\n");
  214.         printf("quit\tq\tquit\n");
  215.         break;
  216.       case CONT:
  217.         sscanf(buf, "%s", buf);
  218.         if (buf[0])
  219.         {
  220.           v = syms_name2val(buf);
  221.           if (undefined_symbol)
  222.             break;
  223.           dr3 = v+ARENA;
  224.           dr7 |= 0xc0;
  225.         }
  226.         else
  227.           dr7 &= ~0xc0;
  228.         olddr7 = dr7;
  229.         dr7 = 0;
  230.         tss_ptr->tss_eflags |= 0x0100;
  231.         go_til_stop();
  232.         dr7 = olddr7;
  233.         if (tss_ptr->tss_irqn == 1)
  234.         {
  235.           tss_ptr->tss_eflags &= ~0x0100;
  236.           tss_ptr->tss_eflags |= 0x10000;
  237.           go_til_stop();
  238.           if (tss_ptr->tss_irqn == 1)
  239.             tssprint(tss_ptr);
  240.         }
  241.         print_reason();
  242.         dr3 = unassemble(tss_ptr->tss_eip, 1) + ARENA;
  243.         break;
  244.       case STEP:
  245.         if (rem_cmd != cmd)
  246.           n = 1;
  247.         sscanf(buf, "%d", &n);
  248.         tss_ptr->tss_eflags |= 0x0100;
  249.         for (i=0; i<n; i++)
  250.         {
  251.           olddr7 = dr7;
  252.           dr7 = 0;
  253.           go_til_stop();
  254.           dr7 = olddr7;
  255.           print_reason();
  256.           dr3 = unassemble(tss_ptr->tss_eip, 1) + ARENA;
  257.           if (tss_ptr->tss_irqn != 1)
  258.             break;
  259.         }
  260.         tss_ptr->tss_eflags &= ~0x0100;
  261.         break;
  262.       case NEXT:
  263.         if (rem_cmd != cmd)
  264.           n = 1;
  265.         sscanf(buf, "%d", &n);
  266.         for (i=0; i<n; i++)
  267.         {
  268.           olddr7 = dr7;
  269.           dr7 &= ~0xc0;
  270.           dr7 |= 0xc0;
  271.           if (last_unassemble_unconditional ||
  272.               last_unassemble_jump)
  273.             tss_ptr->tss_eflags |= 0x0100; /* step */
  274.           else
  275.             tss_ptr->tss_eflags &= ~0x0100;
  276.           go_til_stop();
  277.           dr7 = olddr7;
  278.           print_reason();
  279.           dr3 = unassemble(tss_ptr->tss_eip, 1) + ARENA;
  280.           if (tss_ptr->tss_irqn != 1)
  281.             break;
  282.         }
  283.         tss_ptr->tss_eflags &= ~0x0100;
  284.         break;
  285.       case WHERE:
  286.         v = tss_ptr->tss_ebp;
  287.         vaddr = tss_ptr->tss_eip;
  288.         printf("0x%08lx %s", vaddr, syms_val2name(vaddr, &delta));
  289.         name = syms_val2line(vaddr, &i, 0);
  290.         if (name)
  291.           printf(", line %d in file %s", i, name);
  292.         else if (delta)
  293.           printf("%+ld", delta);
  294.         mputchar('\n');
  295.         do {
  296.           if (v == 0)
  297.             break;
  298.           rem_v = peek32(v+ARENA);
  299.           if (rem_v == 0)
  300.             break;
  301.           vaddr = peek32(v+ARENA+4);
  302.           printf("0x%08lx %s", vaddr, syms_val2name(vaddr, &delta));
  303.           name = syms_val2line(vaddr, &i, 0);
  304.           if (name)
  305.             printf(", line %d in file %s", i, name);
  306.           else if (delta)
  307.             printf("%+ld", delta);
  308.           mputchar('\n');
  309.           v = rem_v;
  310.         } while ((v>=tss_ptr->tss_esp) && (v<0x90000000L));
  311.         break;
  312.       case WHEREIS:
  313.         sscanf(buf, "%s", buf2);
  314.         if (strpbrk(buf2, "*?"))
  315.         {
  316.           syms_listwild(buf2);
  317.           break;
  318.         }
  319.         if (buf2[0])
  320.           vaddr = syms_name2val(buf2);
  321.         if (undefined_symbol)
  322.           break;
  323.         name = syms_val2name(vaddr, &delta);
  324.         printf("0x%08lx %s", vaddr, name);
  325.         if